import http from "http";
import https from "https";
import ws from "ws";
import { Connector } from "./Connector";
import { ISocket, miscCfg } from "../util/defines";

/**
 * 客户端连接服务Webscoket
 */
export class ConnectorWs extends Connector {

    svr: ws.Server;

    private _onSocket: (socket: ISocket) => void;

    start(port: number, onStart: () => void, onSocket: (socket: ISocket) => void, onError: (err: Error) => void): void {
        this._onSocket = onSocket;
        let httpSvr = miscCfg.ssl ? https.createServer(miscCfg.ssl) : http.createServer();
        this.svr = new ws.Server({ server: httpSvr });
        this.svr.on("connection", this.onConnection.bind(this));
        this.svr.on("error", onError);
        httpSvr.listen(port, onStart);
    }

    private onConnection(socket: ws.WebSocket, req: http.IncomingMessage) {
        this._onSocket(new ConnectorWsSocket(socket, req.socket.remoteAddress));
    }

}

class ConnectorWsSocket implements ISocket {

    socket: ws.WebSocket;
    remoteAddress: string;
    dataMaxLen: number = miscCfg.dataMaxLen;

    constructor(socket: ws.WebSocket, remoteAddress: string) {
        this.socket = socket;
        this.socket.binaryType = "nodebuffer";
        this.remoteAddress = remoteAddress;
    }

    send(data: Buffer): void {
        this.socket.send(data);
    }

    on(event: "data", onData: (data: Buffer) => any): void;
    on(event: "close", onClose: () => any): void;
    on(event: "error", onError: (err: Error) => any): void;
    on(event: "close" | "error" | "data", listener: (...args: any[]) => any): void;
    on(event: any, listener: any): void {
        this.socket.on(event == "data" ? "message" : event, listener);
    }

    off(event: "close" | "error" | "data", listener: (...args: any[]) => any): void {
        this.socket.off(event == "data" ? "message" : event, listener);
    }

    close(): void {
        this.socket.close();
    }

}